home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™ 1987-1994 / MacHack™ '87 / Source ƒ.sea / Source ƒ / Pascal ƒ / Transskel.pas ƒ / skel demos / MultiSkel ƒ / MSkelRgn.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-01-07  |  5.0 KB  |  216 lines  |  [TEXT/PJMM]

  1. {    TransSkel multiple-window demonstration: Region module}
  2.  
  3. {    This module handles a window in which the mouse may be clicked and}
  4. {    dragged to draw rectangles.  The rects so drawn are combined into}
  5. {    a single region, the outline of which is drawn.  Rects drawn while}
  6. {    the shift key is held down are subtracted from the region.}
  7. {    Double-clicking the mouse clears the display.  If the window is}
  8. {    resized, the region that is drawn is resized as well.}
  9.  
  10. {    14 June 1986        Paul DuBois}
  11.  
  12. {    Changes:}
  13. {    07/08/86 Changed outline so that it's drawn as a marquee.}
  14. {    Ported to LightSpeed Pascal 7 January 1987                    }
  15. {    By Owen Hartnett, Ωhm Software                                }
  16.  
  17. UNIT regionpas;
  18. INTERFACE
  19.  
  20.     USES
  21.         transSkelpas, multiSkelGlobs, common;
  22.  
  23.     PROCEDURE RgnWindInit;
  24.  
  25.  
  26. IMPLEMENTATION
  27.  
  28.     VAR
  29.         rgnPortRect : Rect;    { portRect size - for detecting wind grows }
  30.         selectRgn : RgnHandle;        { current region to be drawn }
  31.         selectWhen : longint;        { time of last click }
  32.         selectWhere : Point;    { location of last click }
  33.         marqueePat : Pattern;
  34.  
  35.     PROCEDURE Clobber;
  36.  
  37.     BEGIN
  38.         DisposeRgn(selectRgn);
  39.         CloseWindow(rgnWind);
  40.     END;
  41.  
  42. {    While mouse is down, draw gray selection rectangle in the current}
  43. {    port.  Return the resultant rect in dstRect.  The rect is always}
  44. {    clipped to the current portRect.}
  45.  
  46.  
  47.     PROCEDURE DoSelectRect (startPoint : point;
  48.                                     VAR dstRect : Rect);
  49.  
  50.         VAR
  51.             pt, dragPt : Point;
  52.             rClip : Rect;
  53.             thePort : GrafPtr;
  54.             result : Boolean;
  55.             ps : PenState;
  56.             i : integer;
  57.  
  58.     BEGIN
  59.         GetPort(thePort);
  60.         rClip := thePort^.portRect;
  61.         rClip.right := rClip.right - 15;
  62.         GetPenState(ps);
  63.         PenPat(gray);
  64.         PenMode(patXor);
  65.         dragPt := startPoint;
  66.         Pt2Rect(dragPt, dragPt, dstRect);
  67.         FrameRect(dstRect);
  68.         WHILE StillDown DO
  69.             BEGIN
  70.                 GetMouse(pt);
  71.                 IF NOT EqualPt(pt, dragPt) THEN    { mouse has moved, change region }
  72.                     BEGIN
  73.                         FrameRect(dstRect);
  74.                         dragPt := pt;
  75.                         Pt2Rect(dragPt, startPoint, dstRect);
  76.                         result := SectRect(dstRect, rClip, dstRect);
  77.                         FrameRect(dstRect);
  78.                         FOR i := 0 TO 1000 DO
  79.                             ;
  80.                     END;
  81.             END;
  82.         FrameRect(dstRect);    { erase last rect }
  83.         SetPenState(ps);
  84.     END;
  85.  
  86.     PROCEDURE MarqueeRgn (r : RgnHandle);
  87.  
  88.         VAR
  89.             p : PenState;
  90.             b : Byte;
  91.             i : integer;
  92.  
  93.     BEGIN
  94.         GetPenState(p);
  95.         PenPat(marqueePat);
  96.         PenMode(patCopy);
  97.         FrameRgn(r);
  98.         SetPenState(p);
  99.         b := marqueePat[0];        { shift pattern for next call }
  100.         FOR i := 0 TO 6 DO
  101.             marqueePat[i] := marqueePat[i + 1];
  102.         marqueePat[7] := b;
  103.     END;
  104.  
  105.     PROCEDURE Idle;
  106.  
  107.         VAR
  108.             i : integer;
  109.  
  110.     BEGIN
  111.         SetWindClip(rgnWind);
  112.         MarqueeRgn(selectRgn);    { draw selection region outline }
  113.         ResetWindClip;            { restore previous clipping }
  114.     END;
  115.  
  116. {    On double-click, clear window.  On single click, draw gray selection}
  117. {    rectangle as long as mouse is held down.  If user draws non-empty rect,}
  118. {    then add it to the selection region and redraw the region's outline.}
  119. {    If the shift-key was down, then subtract the selection region instead}
  120. {    and redraw.}
  121.  
  122.  
  123.     PROCEDURE Mouse (thePt : Point;
  124.                                     t : longint;
  125.                                     mods : integer);
  126.  
  127.         VAR
  128.             r : Rect;
  129.             rgn : RgnHandle;
  130.  
  131.     BEGIN
  132.         r := rgnWind^.portRect;
  133.         IF thePt.h < r.right - 15 THEN        { must not click in right edge }
  134.             BEGIN
  135.                 IF (t - selectWhen <= GetDblTime) THEN    { it's a double-click }
  136.                     BEGIN
  137.                         selectWhen := 0;        { don't take next click as dbl-click }
  138.                         SetWindClip(rgnWind);
  139.                         EraseRgn(selectRgn);
  140.                         ResetWindClip;
  141.                         SetEmptyRgn(selectRgn);    { clear region }
  142.                     END
  143.                 ELSE
  144.                     BEGIN
  145.                         selectWhen := t;                { update click variables }
  146.                         selectWhere := thePt;
  147.                         DoSelectRect(thePt, r);    { draw selection rectangle }
  148.                         IF NOT EmptyRect(r) THEN
  149.                             BEGIN
  150.                                 EraseRgn(selectRgn);
  151.                                 selectWhen := 0;
  152.                                 rgn := NewRgn;
  153.                                 RectRgn(rgn, r);
  154.                                 IF (Bitand(mods, shiftKey)) <> 0 THEN        { test shift key }
  155.                                     DiffRgn(selectRgn, rgn, selectRgn)
  156.                                 ELSE
  157.                                     unionRgn(selectRgn, rgn, selectRgn);
  158.                                 DisposeRgn(rgn);
  159.                             END;
  160.                     END;
  161.             END;
  162.     END;
  163.  
  164. {    Redraw the current region.  If the window was resized, resize}
  165. {    the region to fit.}
  166.  
  167.     PROCEDURE Update (resized : Boolean);
  168.  
  169.         VAR
  170.             r : Rect;
  171.  
  172.     BEGIN
  173.         EraseRect(rgnWind^.portRect);
  174.         IF resized THEN
  175.             BEGIN
  176.                 r := rgnWind^.portRect;
  177.                 rgnPortRect.right := rgnPortrect.right - 15;    { don't use right edge of window }
  178.                 r.right := r.right - 15;
  179.                 MapRgn(selectRgn, rgnPortRect, r);
  180.                 rgnPortRect := rgnWind^.portRect
  181.             END;
  182.         DrawGrowBox(rgnWind);
  183.         idle;
  184.     END;
  185.  
  186.     PROCEDURE Activate (active : Boolean);
  187.  
  188.     BEGIN
  189.         DrawGrowBox(rgnWind);
  190.         IF active THEN
  191.             DisableItem(editMenu, 0)
  192.         ELSE
  193.             EnableItem(editMenu, 0);
  194.         DrawMenuBar;
  195.     END;
  196.  
  197.     PROCEDURE RgnWindInit;
  198.  
  199.     BEGIN
  200.         StuffHex(@marqueePat, '0f87c3e1f0783c1e');
  201.         rgnWind := GetNewWindow(rgnWindRes, NIL, WindowPtr(-1));
  202.         SkelWindow(rgnWind, @Mouse, NIL, @update, @activate, NIL, @Clobber, @Idle, true);
  203.         { ignore keyclicks }
  204.         { no close proc }
  205.     { disposal proc }
  206.         { idle proc }
  207.  
  208.         rgnPortRect := rgnWind^.portRect;
  209.         selectRgn := NewRgn;    { selected region empty initially }
  210.  
  211.         selectWhen := 0;    { first click can't be taken as dbl-click }
  212.     END;
  213.  
  214.  
  215.  
  216. END.